{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "entertaining-bronze",
   "metadata": {},
   "source": [
    "# Transmon Analytics: Plotting Eigenvalues as a Function of Offset Charge  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "velvet-cloud",
   "metadata": {},
   "source": [
    "This demo notebook uses the Hamiltonian Cooper Pair Box (Hcpb) class to recreate the plots of energy as a function of offset charge, originally found in Koch et al. Phys. Rev. A 76, 042319 (2007). "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "beginning-wallpaper",
   "metadata": {},
   "source": [
    "We'll start by importing the Hcpb class as well as numpy and matplotlib: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "characteristic-letters",
   "metadata": {},
   "outputs": [],
   "source": [
    "from qiskit_metal.analyses.hamiltonian.transmon_charge_basis import Hcpb\n",
    "import numpy as np \n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "raising-persian",
   "metadata": {},
   "source": [
    "We'll use the variable x to represent the offset charge (ng, measured in units of Cooper pair charge: 2e) which we'll have vary between -2 and 2:  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "silent-toolbox",
   "metadata": {},
   "outputs": [],
   "source": [
    "# We'll use the variable x to represent the offset charge (ng), which will vary from -2.0 to 2.0 \n",
    "x = np.linspace(-2.0,2.0,101)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "casual-wright",
   "metadata": {},
   "source": [
    "Next, we'll define a value for the Josephson Energy (E_J) as well as the ratio between the Josephson Energy and the Charging Energy. We will see that the ratio of E_J/E_C controls the anharmonicity of the qubit as well as the dispersion. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "correct-aside",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define a value of the Josephson Energy (E_J) as well as the ratio between the E_J and the Charging Energy (E_C): \n",
    "E_J = 1000.0 \n",
    "ratio = 1.0 \n",
    "E_C = E_J/ratio "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "micro-horizontal",
   "metadata": {},
   "source": [
    "Now we will actually use the Hcpb class to calculate the transmon eigenvalues for a given value of offset charge. Note that in the plots found in the original paper, the eigenvalues are normalized by 0->1 transition energy evaluated at an offset charge of ng=0.5, so we first calculate that value and use it for normalization later. We create three empty lists, one for each energy level, then populate the lists with the corresponding eigenvalues for a given offset charge. Lastly, we calculate the minimum value of the lowest energy eigenvalue (called \"floor\") and set this to E=0 in our final plots.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "systematic-rogers",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Em/E01')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# we'll normalize the calculated energies by the 0->1 transition state energy evaluated at the degenercy point (ng=0.5)\n",
    "H_norm = Hcpb(nlevels=2, Ej=E_J, Ec=E_C, ng=0.5)\n",
    "norm = H_norm.fij(0,1)\n",
    "\n",
    "# Next we'll empty lists to the first three eigenvalues (m=0, m=1, m=2):\n",
    "E0 = [] \n",
    "E1 = [] \n",
    "E2 = []\n",
    "\n",
    "# For a given value of offset charge (ng, represented by x) we will calculate the CPB Hamiltonian using the previously assigned values of E_J and E_C. Then we calculate the eigenvalue for a given value of m.\n",
    "for i in x: \n",
    "    H = Hcpb(nlevels=3, Ej=E_J, Ec=E_C, ng=i)\n",
    "    E0.append(H.evalue_k(0)/norm)\n",
    "    E1.append(H.evalue_k(1)/norm)\n",
    "    E2.append(H.evalue_k(2)/norm)\n",
    "\n",
    "# define the minimum of E0 and set this to E=0\n",
    "floor = min(E0) \n",
    " \n",
    "plt.plot(x, E0 - floor, 'k')\n",
    "plt.plot(x, E1 - floor, 'r')\n",
    "plt.plot(x, E2 - floor, 'b')\n",
    "plt.xlabel(\"ng\")\n",
    "plt.ylabel(\"Em/E01\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "registered-microphone",
   "metadata": {},
   "source": [
    "You can vary the value of ratio to 5.0, 10.0 and 50.0 to verify that the generated plots match those found in the original paper. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
